home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 351-375 / 351 / pdc / pdcsrc.lzh / PDC / Init.c < prev    next >
C/C++ Source or Header  |  1990-04-06  |  9KB  |  410 lines

  1.  
  2. /* PDC Compiler - A Freely Distributable C Compiler for the Amiga
  3.  *                Based upon prior work by Matthew Brandt and Jeff Lydiatt.
  4.  *
  5.  * PDC Compiler release 3.3 Copyright (C) 1989 Paul Petersen and Lionel Hummel.
  6.  * PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
  7.  *
  8.  * This code is freely redistributable upon the conditions that this 
  9.  * notice remains intact and that modified versions of this file not be 
  10.  * distributed as part of the PDC Software Distribution without the express
  11.  * consent of the copyright holders.
  12.  *
  13.  *------------------------------------------------------------------
  14.  *
  15.  * $Log:    Init.c,v $
  16.  * Revision 3.33  90/04/05  22:35:27  lionel
  17.  * None.
  18.  * 
  19.  * Revision 3.32  90/02/03  16:24:40  lionel
  20.  * None
  21.  * 
  22.  *------------------------------------------------------------------
  23.  */
  24.  
  25. /*
  26.  * Init.c
  27.  * 
  28.  * Initializes all sorts of nodes that go into the symbol table/parse tree.
  29.  * Generate and initialize a node for an auto initialized variable.
  30.  */
  31.  
  32. #include    <stdio.h>
  33. #include    "C.h"
  34. #include    "Expr.h"
  35. #include    "Gen.h"
  36. #include    "Cglbdec.h"
  37.  
  38. extern SYM     *gsearch();
  39. extern SYM     *gsearch();
  40. extern TYP     *exprnc(), *asforcefit(), *deref();
  41. extern long     intexpr(), stringlit();
  42. extern char    *xalloc();
  43. extern double   floatexpr();
  44. extern struct enode *addrexpr();
  45. extern struct enode *makenode();
  46. extern struct amode *gen_expr();
  47.  
  48. void    endinit();
  49.  
  50. int
  51. initstring(tp) 
  52.     TYP            *tp;
  53. {
  54.     int nbytes;
  55.     char    *p;
  56.  
  57.     nbytes = 1;
  58.     while (lastst == sconst) {
  59.         nbytes += strlen(laststr);
  60.         for (p = laststr; *p; ++p)
  61.             genbyte(*p);
  62.         getsym();
  63.     }
  64.     genbyte(0);
  65.     if (nbytes & 1) {
  66.         nbytes++;
  67.         genbyte(0);
  68.     }
  69.  
  70.     return( nbytes );
  71. }
  72.  
  73. int
  74. initarray(tp)
  75.     TYP            *tp;
  76. {
  77.     int             nbytes, num;
  78.     char           *p;
  79.  
  80.     nbytes = 0;
  81.     if (lastst == begin) {
  82.         getsym();   /* skip past the brace */
  83.         if (lastst == sconst &&
  84.             (tp->btp->type == bt_char || tp->btp->type == bt_uchar)) {
  85.             nbytes = initstring(tp);
  86.         }
  87.         else {
  88.             while (lastst != end) {
  89.                 nbytes += inittype(tp->btp);
  90.                 if (lastst == comma)
  91.                     getsym();
  92.                 else if (lastst != end) {
  93.                     error(ERR_PUNCT, NULL);
  94.                     getsym();
  95.                 }
  96.             }
  97.         }
  98.         getsym();   /* skip closing brace */
  99.     }
  100.     else if (lastst == cconst &&
  101.          (tp->btp->type == bt_char || tp->btp->type == bt_uchar)) {
  102.         nbytes = 1;
  103.         genbyte( ival );
  104.         getsym();
  105.     }
  106.     else if (lastst == sconst &&
  107.          (tp->btp->type == bt_char || tp->btp->type == bt_uchar)) {
  108.         nbytes = initstring(tp);
  109.     }
  110.     else if (lastst != semicolon)
  111.         error(ERR_ILLINIT, NULL);
  112.     if (nbytes < tp->size) {
  113.         num = tp->size - nbytes;
  114.         if (num & 1) {  /* Only generate even amounts of storage */
  115.             genbyte(0);
  116.             --num;
  117.         }
  118.         if (num > 0)
  119.             genstorage((int) num);
  120.         nbytes = tp->size;
  121.     }
  122.     else if (tp->size != 0 && nbytes > tp->size)
  123.         error(ERR_INITSIZE, NULL);  /* too many initializers */
  124.     nl();
  125.     return nbytes;
  126. }
  127.  
  128. int
  129. initstruct(tp)
  130.     TYP            *tp;
  131. {
  132.     SYM            *sp;
  133.     int             nbytes;
  134.     int             seen;
  135.  
  136.     if (seen = (lastst == begin))
  137.         needpunc(begin);
  138.  
  139.     nbytes = 0;
  140.     sp = tp->lst.head;  /* start at top of symbol table */
  141.  
  142.     if (sp != NULL) {
  143.         if (nbytes < sp->value.i) {
  144.             while (nbytes < sp->value.i) {  /* align properly */
  145.                 genbyte(0);
  146.                 ++nbytes;
  147.             }
  148.         }
  149.         nbytes += inittype(sp->tp);
  150.         sp = sp->next;
  151.  
  152.         while (sp != NULL) {
  153.             if (lastst == end)
  154.                 goto done;
  155.             if (lastst == comma)
  156.                 getsym();
  157.             if (nbytes < sp->value.i) {
  158.                 while (nbytes < sp->value.i) {  /* align properly */
  159.                     genbyte(0);
  160.                     ++nbytes;
  161.                 }
  162.             }
  163.             nbytes += inittype(sp->tp);
  164.             sp = sp->next;
  165.         }
  166.     }
  167. done:
  168.     if (nbytes < tp->size)
  169.         genstorage((int) (tp->size - nbytes));
  170.     if (seen) {
  171.         if (lastst == comma)
  172.             getsym();
  173.         needpunc(end);
  174.     }
  175.     nl();
  176.     return tp->size;
  177. }
  178.  
  179. int
  180. initchar()
  181. {
  182.     int             i;
  183.  
  184.     i = (int) intexpr();
  185.     genbyte(i);
  186.     return 1;
  187. }
  188.  
  189. int
  190. initshort()
  191. {
  192.     genword((long) intexpr());
  193.     return 2;
  194. }
  195.  
  196. int
  197. initlong()
  198. {
  199.     genlong((long) intexpr());
  200.     return 4;
  201. }
  202.  
  203. int
  204. initsingle()
  205. {
  206.     gensingle((double) floatexpr());
  207.     return 4;
  208. }
  209.  
  210. int
  211. initdouble()
  212. {
  213.     gendouble((double) floatexpr());
  214.     return 8;
  215. }
  216.  
  217. int
  218. initpointer()
  219. {
  220.     SYM            *sp;
  221.     struct enode   *ep;
  222.     int             offset;
  223.     int             seen;
  224.  
  225.     if (seen = (lastst == begin))
  226.         getsym();
  227.  
  228.     if ((ep = addrexpr()) == NULL)
  229.         error(ERR_SYNTAX, NULL);
  230.     else if (ep->nodetype == en_icon)
  231.         genlong(ep->v.i);
  232.     else if (ep->nodetype == en_labcon)
  233.         gen_labref((int) ep->v.i, 0);
  234.     else if (ep->nodetype == en_add || ep->nodetype == en_sub) {
  235.         if (ep->v.p[0]->nodetype != en_nacon &&
  236.             ep->v.p[0]->nodetype != en_labcon)
  237.             swap_nodes(ep);
  238.         if (ep->v.p[0]->nodetype != en_nacon &&
  239.             ep->v.p[0]->nodetype != en_labcon)
  240.             error(ERR_IDEXPECT, NULL);
  241.         else {
  242.             if (ep->v.p[0]->nodetype == en_labcon) {
  243.                 offset = ep->v.p[1]->v.i;
  244.                 if (ep->nodetype == en_add)
  245.                     gen_labref((int) ep->v.p[0]->v.i, offset);
  246.                 else
  247.                     gen_labref((int) ep->v.p[0]->v.i, -offset);
  248.             }
  249.             else if ((sp = gsearch(ep->v.p[0]->v.sp)) == NULL)
  250.                 error(ERR_UNDEFINED, ep->v.p[0]->v.sp);
  251.             else {
  252.                 if (sp->storage_class == sc_auto)
  253.                     error(ERR_NOINIT, NULL);
  254.                 else if (ep->v.p[1]->nodetype != en_icon)
  255.                     error(ERR_SYNTAX, NULL);
  256.                 else {
  257.                     offset = ep->v.p[1]->v.i;
  258.                     if (ep->nodetype == en_add)
  259.                         genref(sp, offset);
  260.                     else
  261.                         genref(sp, -offset);
  262.                 }
  263.             }
  264.         }
  265.     }
  266.     else if (ep->nodetype == en_nacon) {
  267.         if ((sp = gsearch(ep->v.sp)) == NULL)
  268.             error(ERR_UNDEFINED, ep->v.p[0]->v.sp);
  269.         else {
  270.             if (sp->storage_class == sc_auto)
  271.                 error(ERR_NOINIT, NULL);
  272.             else
  273.                 genref(sp, 0);
  274.         }
  275.     }
  276.     else
  277.         error(ERR_SYNTAX, NULL);
  278.     endinit();
  279.  
  280.     if (seen)
  281.         needpunc(end);
  282.  
  283.     return 4;       /* pointers are 4 bytes long */
  284. }
  285.  
  286. void
  287. endinit()
  288. {
  289.     if (lastst != comma && lastst != semicolon && lastst != end) {
  290.         error(ERR_PUNCT, NULL);
  291.         while (lastst != comma && lastst != semicolon &&
  292.                lastst != end && lastst != eof)
  293.             getsym();
  294.     }
  295. }
  296.  
  297. int
  298. inittype(tp)
  299.     TYP            *tp;
  300. {
  301.     int             nbytes;
  302.  
  303.     if (tp == NULL)
  304.         return(0);
  305.  
  306.     switch (tp->type) {
  307.  
  308.     case bt_char:
  309.     case bt_uchar:
  310.         nbytes = initchar();
  311.         break;
  312.     case bt_short:
  313.     case bt_ushort:
  314.     case bt_enum:
  315.         nbytes = initshort();
  316.         break;
  317.     case bt_float:
  318.         nbytes = initsingle();
  319.         break;
  320.     case bt_double:
  321.         nbytes = initdouble();
  322.         break;
  323.     case bt_pointer:
  324.         if (tp->val_flag) {
  325.             nbytes = initarray(tp);
  326.             if (nbytes > tp->size) {
  327.                 tp->size = nbytes;
  328.             }
  329.         }
  330.         else
  331.             nbytes = initpointer();
  332.         break;
  333.     case bt_long:
  334.     case bt_unsigned:
  335. #ifdef OLD_tfunc
  336.         nbytes = initlong();
  337. #else
  338.         nbytes = initpointer();
  339. #endif
  340.         break;
  341.     case bt_struct:
  342.         nbytes = initstruct(tp);
  343.         break;
  344.     default:
  345.         error(ERR_NOINIT, NULL);
  346.         nbytes = 0;
  347.     }
  348.     return nbytes;
  349. }
  350.  
  351. void
  352. doinit(sp)
  353.     SYM            *sp;
  354. {
  355.     if (lastst == assign)
  356.         dseg();     /* initialize into data segment */
  357.     else
  358.         bseg();     /* generate storage in the bss  */
  359.  
  360.     nl();           /* start a new line in object */
  361.     if (sp->storage_class == sc_static)
  362.         put_label((long) (sp->value.i));
  363.     else
  364.         gen_strlab(sp->name);
  365.     if (lastst != assign)
  366.         genstorage((int) (sp->tp->size));
  367.     else {
  368.         getsym();
  369.         inittype(sp->tp);
  370.     }
  371.     nl();
  372.     endinit();
  373. }
  374.  
  375.  
  376. void
  377. doinitauto(sp)
  378.     SYM            *sp;
  379. {
  380.     TYP            *tp1, *tp2;
  381.     struct enode   *ep1, *ep2;
  382.     struct snode   *snp;
  383.  
  384.     if (lastst != assign || sp->storage_class != sc_auto)
  385.         return;
  386.  
  387.     getsym();       /* We found an auto initilized variable */
  388.  
  389.     snp = (struct snode *) xalloc(sizeof(struct snode));
  390.     snp->stype = st_expr;
  391.  
  392.     ep1 = makenode(en_autocon, sp->value.i, NULL);
  393.     ep1->constflag = 0;
  394.  
  395.     tp1 = sp->tp;
  396.     tp1 = deref(&ep1, tp1);
  397.  
  398.     tp2 = exprnc(&ep2);
  399.  
  400.     if (tp2 == 0 || !lvalue(ep1))
  401.         error(ERR_LVALUE, NULL);
  402.     else {
  403.         tp1 = asforcefit(&ep1, tp1, &ep2, tp2);
  404.         ep1 = makenode(en_assign, ep1, ep2);
  405.         snp->exp = ep1;
  406.         snp->next = NULL;
  407.         addauto(snp);
  408.     }
  409. }
  410.